package cn.ibizlab.eam.core.extensions.service;

import cn.ibizlab.eam.core.eam_core.domain.*;
import cn.ibizlab.eam.core.eam_core.filter.EMWPListSearchContext;
import cn.ibizlab.eam.core.eam_core.service.*;
import cn.ibizlab.eam.core.eam_core.service.impl.EMWPListServiceImpl;
import cn.ibizlab.eam.core.util.helper.Aops;
import cn.ibizlab.eam.util.dict.StaticDict;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Primary;

import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 实体[采购申请] 自定义服务对象
 */
@Slf4j
@Primary
@Service("EMWPListExService")
public class EMWPListExService extends EMWPListServiceImpl {

    @Autowired
    private IEMPOService iempoService;

    @Override
    protected Class currentModelClass() {
        return com.baomidou.mybatisplus.core.toolkit.ReflectionKit.getSuperClassGenericType(this.getClass().getSuperclass(), 1);
    }

    /**
     * [Confirm:确定询价] 行为扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public EMWPList confirm(EMWPList et) {
        et = this.get(et.getEmwplistid());
        if (et == null) {
            throw new RuntimeException("采购信息不存在,无法完成操作");
        }
        et.setWfstep(StaticDict.EMWPLISTWFSTEP.ITEM_60.getValue());
        if (et.getEmserviceid() == null) {
            throw new RuntimeException("服务商信息不存在,无法完成操作");
        }
        Aops.getSelf(this).update(et);
        return super.confirm(et);
    }

    /**
     * [FillCosted:询价填报完成] 行为扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public EMWPList fillCosted(EMWPList et) {
        if (et.getEmwplistid() == null) {
            throw new RuntimeException("采购信息不存在,无法完成操作");
        }
        et = this.get(et.getEmwplistid());
        List<EMWPListCost> emwpListCosts = emwplistcostService.selectByWplistid(et.getEmwplistid());
        // 判断是否存在询价单
        if (emwpListCosts.isEmpty()) {
            throw new RuntimeException("询价单不存在,无法完成操作");
        }
        //判断是否需要三次询价，询价次数是否满足
        if (et.getNeed3q().equals(1)) {
            if (emwpListCosts.size() < 3) {
                throw new RuntimeException("不满足三次询价,无法完成操作");
            }
        }
        // 询价满足，完成询价填报
        et.setWfstep(StaticDict.EMWPLISTWFSTEP.ITEM_50.getValue());
        Aops.getSelf(this).update(et);
        return super.fillCosted(et);
    }

    @Override
    public boolean create(EMWPList et) {
        Calendar calendar = Calendar.getInstance();
        // 希望到货时间=系统当前时间+10天
        if (et.getHdate() == null) {
            calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 10);
            et.setHdate(new Timestamp(calendar.getTimeInMillis()));
        }
        //上次请购时间
        if (et.getLastdate() == null) {
            EMWPListSearchContext ctx = new EMWPListSearchContext();
            ctx.setN_itemid_eq(et.getItemid());
            Sort sort = Sort.by("adate").descending();
            ctx.setPageSort(sort);
            List<EMWPList> emwpLists = this.searchDefault(ctx).getContent();
            if (emwpLists.size() > 0) {
                et.setLastdate(emwpLists.get(0).getAdate());
            }
        }
        return super.create(et);
    }

    /**
     * [GenPO:生成订单] 行为扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public EMWPList genPO(EMWPList et) {
        //供应商相同，多条采购信息生成一条订单，并且只会生成一条订单信息
        //每条采购信息生成对应订单条目  一对一
        if (et == null) {
            throw new RuntimeException("采购信息不存在，无法完成操作");
        }
        List<String> emwpListids = Arrays.asList(et.getEmwplistid().split(","));
        List<EMWPList> emwpLists = this.getEmwplistByIds(emwpListids);
        //key是服务商id  value是订单信息
        HashMap<String, EMPO> EMPOMap = new HashMap<>();
        //key是服务商id   value是订单条目
        HashMap<String, List<EMPODetail>> EMPODetailMap = new HashMap<>();

        for (int i = 0; i < emwpLists.size(); i++) {
            EMWPList emwpList = emwpLists.get(i);
            //比较之前是否有相同的供应商
            boolean result = EMPOMap.containsKey(emwpList.getEmserviceid());
            if (!result) {
                EMPO empo = new EMPO();
                BeanCopier copierCheck = BeanCopier.create(EMWPList.class, EMPO.class, false);
                copierCheck.copy(emwpList, empo, null);
                empo.setLabserviceid(emwpList.getEmserviceid());
                empo.setPdate(emwpList.getAdate());
                empo.setEmponame(emwpList.getRempname());
                empo.setPostate(StaticDict.EMPOSTATE.ITEM_10.getValue());
                empo.setWfstep(StaticDict.EMPOWFSTEP.ITEM_40.getValue());
                EMPOMap.put(empo.getLabserviceid(), empo);
            }

            EMItem emItem = emitemService.get(emwpList.getItemid());
            List<EMWPListCost> emwpListCosts = emwplistcostService.selectByWplistid(emwpList.getEmwplistid());
            EMWPListCost emwpListCost = emwpListCosts.stream().findFirst().get();
            //订单条目生成对应数据
            EMPODetail empoDetail = new EMPODetail();
            BeanCopier copierCheck = BeanCopier.create(EMWPList.class, EMPODetail.class, false);
            copierCheck.copy(emwpList, empoDetail, null);
            //TODO  待修改
            //税率
            double taxrate = emwpListCost.getTaxrate() == null ? 0.17 : emwpListCost.getTaxrate();
            //单价
            double price = emwpListCost.getPrice() == null ? 0 : emwpListCost.getPrice();

            empoDetail.setRdate(emwpList.getHdate());
            empoDetail.setEmpodetailname(emwpList.getEmwplistname() + emwpList.getEmwplistid());
            empoDetail.setPrice(price);
            empoDetail.setTaxrate(taxrate);
            empoDetail.setAmount(price * emwpList.getAsum());
            empoDetail.setShf(empoDetail.getTaxrate() * empoDetail.getAmount());
            empoDetail.setLabserviceid(emwpList.getEmserviceid());
            empoDetail.setWplistid(emwpList.getEmwplistid());
            empoDetail.setListprice(emwpListCost.getListprice());
            //TODO 待确认
            //empoDetail.setEmpid();
            //empoDetail.setRsum();
            empoDetail.setPsum(emwpList.getAsum());
            //有多条采购信息，并且服务商相同
            if (result) {
                List<EMPODetail> details = EMPODetailMap.get(emwpList.getEmserviceid());
                details.add(empoDetail);
                EMPODetailMap.put(emwpList.getEmserviceid(), details);

                EMPO empo = EMPOMap.get(emwpList.getEmserviceid());
                empo.setPoamount(empoDetail.getAmount() + empo.getPoamount());
                Double maxprice = (empoDetail.getPrice() > empo.getMaxprice()) ? empoDetail.getPrice() : empo.getMaxprice();
                empo.setMaxprice(maxprice);
                EMPOMap.put(emwpList.getEmserviceid(), empo);
            } else {
                //有一条或多条采购信息，但供应商都不一样
                EMPO empo = EMPOMap.get(emwpList.getEmserviceid());
                empo.setPoamount(empoDetail.getAmount());
                empo.setMaxprice(empoDetail.getPrice());
                EMPOMap.put(emwpList.getEmserviceid(), empo);
                List<EMPODetail> empoDetails = new ArrayList<>();
                empoDetails.add(empoDetail);
                EMPODetailMap.put(emwpList.getEmserviceid(), empoDetails);
            }

            //修改已生产订单的对应状态
            emwpList.setFocusNull(null);
            emwpList.setWfstep("");
            emwpList.setWfstate(Integer.valueOf(StaticDict.WFStates.ITEM_2.getValue()));
            emwpList.setWpliststate(StaticDict.EMWPLISTSTATE.ITEM_20.getValue());
            Aops.getSelf(this).update(emwpList);
        }
        //两个map都是供应商为key，key值相同
        for (Map.Entry<String, EMPO> entry : EMPOMap.entrySet()) {
            EMPO empo = entry.getValue();
            iempoService.create(empo);
            List<EMPODetail> details = EMPODetailMap.get(empo.getLabserviceid());
            //去除重复数据
            List<EMPODetail> collect = details.stream().distinct().collect(Collectors.toList());
            for (EMPODetail detail : collect) {
                detail.setPoid(empo.getEmpoid());
                empodetailService.create(detail);
            }
        }
        return super.genPO(et);
    }
}
